This is the workaround that I am currently using, which is just using TipKit's model to drive a popover(). Note that these popovers, in iOS 26, use the iOS 26 LiquidGlass morphing-button popover style.
import SwiftUI
import TipKit
extension View {
func popoverTipWorkaround(_ tip: some Tip) -> some View {
modifier(PopoverTipWorkaround(tip: tip))
}
}
private struct PopoverTipWorkaround<T: Tip>: ViewModifier {
let tip: T
@State private var shouldDisplay = false
func body(content: Content) -> some View {
content
.popover(isPresented: $shouldDisplay) {
TipView(tip)
.tipViewStyle(NoDismissTipStyle())
.tipBackground(.clear)
.presentationCompactAdaptation(.popover)
}
.task {
for await status in tip.statusUpdates {
if status == .available {
shouldDisplay = true
}
}
}
}
}
private struct NoDismissTipStyle: TipViewStyle {
func makeBody(configuration: Configuration) -> some View {
VStack(alignment: .leading) {
configuration.title
configuration.message
}
.padding()
}
}
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags: